package com.tos.controller;

import com.alibaba.fastjson.JSONArray;
import com.tos.pojo.Bill;
import com.tos.pojo.Passenger;
import com.tos.service.BillService;
import com.tos.util.Constants;
import com.tos.util.PDFOutput;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/bill")
public class BillController {

    @Autowired
    private BillService billService;



    @RequestMapping("/getBills")
    public List<Bill> getBills(@RequestBody Passenger passenger) {

        List<Bill> bills = billService.getBills(passenger.getPhone());
        for(Bill bill:bills){
            if(bill.getSeatType()==1){
                bill.setSeatTypeStr("头等舱");
            }
            else{
                bill.setSeatTypeStr("经济舱");
            }
        }
        return bills;
    }

    @RequestMapping("/deleteBill")
    public void deleteBill(HttpServletResponse response, String billId) throws IOException {
        boolean success = billService.deleteBill(billId);
        //System.out.println(billId);
        HashMap<String, String> resultMap = new HashMap<>();
        if (success) {
            resultMap.put("delResult","true");
        }else {
            resultMap.put("delResult","false");
        }
        //把resultMap转换成json对象输出
        response.setContentType("application/json");
        PrintWriter outPrintWriter = response.getWriter();
        outPrintWriter.write(JSONArray.toJSONString(resultMap));
        outPrintWriter.flush();
        outPrintWriter.close();
    }


    @PostMapping(value = "/upload")
    public void uploadFile(@RequestParam("files") MultipartFile[] files) throws IOException {
        // 1. 用数组MultipartFile[]来表示多文件,所以遍历数组,对其中的文件进行逐一操作
        for (MultipartFile file : files) {
            // 2. 通过一顿file.getXXX()的操作,获取文件信息。
            // 2.1 这里用文件名举个栗子
            String filename = file.getOriginalFilename();
            // 3. 接下来调用方法来保存文件到本地磁盘,返回的是保存后的文件路径
            String filePath = savaFileByNio((FileInputStream) file.getInputStream(), filename);
            // 4. 保存文件信息到数据库
            // 4.1 搞个实体类，把你需要的文件信息保存到实体类中
            // 4.2 调用Service层或者Dao层，保存数据库即可。
        }
    }

    public static String savaFileByNio(FileInputStream fis, String fileName) {
        // 这个路径最后是在: 你的项目路径/FileSpace  也就是和src同级
        String fileSpace = System.getProperty("user.dir") + File.separator + "FileSpace";
        String path = fileSpace + File.separator + fileName;
        // 判断父文件夹是否存在
        File file = new File(path);
        if (file.getParentFile() != null || !file.getParentFile().isDirectory()) {
            file.getParentFile().mkdirs();
        }
        // 通过NIO保存文件到本地磁盘
        try {
            FileOutputStream fos = new FileOutputStream(path);
            FileChannel inChannel = fis.getChannel();
            FileChannel outChannel = fos.getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
            inChannel.close();
            outChannel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }


    @GetMapping(value = "/download/fileId/{fileId}")
    public ResponseEntity<ByteArrayResource> downloadFile(@PathVariable("fileId") String fileId, HttpServletRequest request) throws Exception {
        // 这里根据我给定的fileId来下载指定的文件，
        // 如果你想根据其他方式来下载指定文件的话，请自己修改业务逻辑
        // 1. 根据fileId从数据库中获取到指定的文件信息，包括文件名、文件存储地址等等。
        // 1.1 假设我已经获取到了文件信息。
        String fileName = "XXXX";
        String filePath = "XXXX";

        // 2. 解决下载的文件的文件名出现中文乱码
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            // IE浏览器
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
        } else {
            // 非IE浏览器
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }

        // 3. 下载文件
        byte[] data = Files.readAllBytes(Paths.get(filePath));
        ByteArrayResource resource = new ByteArrayResource(data);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName)
                .contentType(MediaType.APPLICATION_OCTET_STREAM).contentLength(data.length)
                .body(resource);
    }


    @RequestMapping("downloadBill")
    public ResponseEntity<byte[]> download(HttpServletRequest request, String bill)throws Exception {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date newDate = new Date();
        String createDate = sdf.format(newDate);
        String[] dateArr = createDate.split("-");
        System.out.println(bill);
        String[] billArr = bill.split(";");
        //设置座位类型
        billArr[6] = "1".equals(billArr[6]) ? "头等舱" : "经济舱";

        //bill的pdf的表单域个数
        String[] pdfArgsArr = new String[11];
        System.arraycopy(dateArr, 0, pdfArgsArr, 0, 3);
        System.arraycopy(billArr, 0, pdfArgsArr, 3, 8);
        //得到pdf的文件名
        String path = request.getServletContext().getRealPath("/download");
        String fileName = PDFOutput.generatePDF(request, pdfArgsArr, 1);

        //设置响应头
        //创建http头信息的对象
        HttpHeaders header=new HttpHeaders();
        //标记以流的方式做出响应
        header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //设置以弹窗的方式提示用户下载
        //attachment 表示以附件的形式响应给客户端
        header.setContentDispositionFormData("attachment", URLEncoder.encode(fileName,"utf-8"));
        File f=new File(path + "/" + fileName);
        ResponseEntity<byte[]> resp=
                new ResponseEntity<byte[]>
                        (FileUtils.readFileToByteArray(f), header, HttpStatus.CREATED);
        //前端得到文件后，删除服务器的pdf，以免占用资源
        PDFOutput.deleteFile(path + "/" + fileName);
        return resp;

    }

}
